package speedchina.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import speedchina.controller.BaseController;
import speedchina.entity.BaseEntity;
import speedchina.entity.user.Resource;
import speedchina.entity.user.Role;
import speedchina.entity.user.User;
import speedchina.enums.ResultEnum;
import speedchina.exception.BaseException;
import speedchina.service.user.ResourceService;
import speedchina.vo.ResultVO;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 菜单信息- 获取相关资源
 *
 * @author 占超群
 */
@Controller
@RequestMapping("/system/resource")
public class ResourceController extends BaseController
{

    @Autowired
    private ResourceService resourceService;

    /**
     * 资源(菜单)管理
     *
     * @return 资源(菜单)管理页面
     */
    @RequiresPermissions("system:resource:view")
    @GetMapping("/view")
    public String resource()
    {
        return "menu/resource";
    }

    /**
     * 根据资源信息列表
     *
     * @param resource 资源信息
     * @return 资源列表
     */
    @RequiresPermissions("system:resource:list")
    @GetMapping("/list")
    @ResponseBody
    public List<Resource> list(Resource resource)
    {
        return resourceService.selectResouceList(resource);
    }

    /**
     * 新增菜单页面
     *
     * @param parentId 父id
     * @param mmap     模型
     * @return 新增菜单页面
     */
    @RequiresPermissions("system:resource:add")
    @GetMapping("/add/{parentId}")
    public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
    {
        Resource resource;
        if (0L != parentId)
        {
            resource = resourceService.selectResourceById(parentId);
        }
        else
        {
            resource = new Resource();
            resource.setId(0L);
            resource.setResourceName("主目录");
        }
        mmap.put("resource", resource);
        return "menu/add";
    }

    /**
     * 新增保存菜单
     *
     * @param resource 资源信息
     * @return 统一结果
     */
    @RequiresPermissions("system:resource:add")
    @RequestMapping("/add")
    @ResponseBody
    public ResultVO addSave(@Valid Resource resource)
    {
        return ResultVO.success(resourceService.insertResource(resource));
    }

    /**
     * 加载角色菜单列表树
     *
     * @param role 角色信息
     * @return 菜单列表
     */
    @GetMapping("/roleResourceTreeData")
    @ResponseBody
    public List<Map<String, Object>> roleMenuTreeData(Role role)
    {
        return resourceService.roleMenuTreeData(role);
    }

    /**
     * 自定义添加菜单
     *
     * @param resource 资源信息
     * @return 添加菜单页
     */
    @RequiresPermissions("system:resource:add")
    @ResponseBody
    @RequestMapping("/addResource")
    public String addResource(@Valid Resource resource)
    {
        // 判断父子菜单
        if ("1".equals(resource.getParentName()))
        {
            resource.setParentId(0L);

        }
        else
        {
            Long parentid = resourceService.selectIdByName(resource.getParentName());
            resource.setParentId(parentid);
        }
        resource.setVisible("0");
        resource.setIcon("&#xe658;");
        //获取当前用户
        User user = (User)SecurityUtils.getSubject().getPrincipal();
        resource.setCreateBy(user.getLoginName());
        resource.setUpdateBy(user.getLoginName());
        resource.setCreateTime(new Date());
        resource.setUpdateTime(new Date());
        resource.setPerms("1");
        //新增
        try
        {
            resourceService.save(resource);
            return "success";
        }
        catch (Exception e)
        {
            throw new BaseException(e);
        }

    }

    /**
     * 加载所有菜单列表树
     *
     * @return 菜单列表树
     */
    @GetMapping("/resourceTreeData")
    @ResponseBody
    public List<Map<String, Object>> resourceTreeData()
    {
        return resourceService.resourceTreeData();
    }

    /**
     * 获取所有父菜单
     *
     * @return 菜单列表
     */
    @GetMapping("/getParentResource")
    @ResponseBody
    public List<Resource> selectParentResource()
    {
        return resourceService.selectParentResource();
    }

    /**
     * 获取所有菜单类型
     *
     * @return 类型列表
     */
    @GetMapping("/getResourceType")
    @ResponseBody
    public List<String> selectResourceType()
    {
        return resourceService.selectResourceType();
    }

    /**
     * 删除指定id的菜单资源
     *
     * @param resourceId 资源id
     * @return 统一结果
     */
    @DeleteMapping("/del/{resourceId}")
    @RequiresPermissions("system:resource:remove")
    @ResponseBody
    public ResultVO del(@PathVariable("resourceId") Long resourceId)
    {
        // 用于存储需要删除的菜单项id
        Set<Long> list = new HashSet<>();
        getTreeMenu(resourceId, list);
        // 删除
        return ResultVO.success(resourceService.removeByIds(list));
    }

    private void getTreeMenu(Long resourceId, Set<Long> list)
    {
        list.add(resourceId);
        // 查询下一级treeMenuList
        List<Resource> childList = this.getChildList(resourceId);
        if (null != childList && childList.size() > 0)
        {
            // 循环查询到的菜单list
            for (Resource resource : childList)
            {
                list.add(resource.getId());
                getTreeMenu(resource.getId(), list);

            }

        }

    }

    public List<Resource> getChildList(Long parentId)
    {
        //判断是否有子菜单
        List<Resource> childList = resourceService.list(
            new QueryWrapper<Resource>().in("parent_id", parentId));
        return childList;
    }

    /**
     * 条件获得所有菜单
     *
     * @param resourceName 资源名
     * @return 菜单列表
     */
    @RequestMapping("/getAll")
    @ResponseBody
    public List<Resource> getAllResource(String resourceName)
    {
        return resourceService.list(
            new QueryWrapper<Resource>().like(StringUtils.isNotBlank(resourceName),
                "resource_name", resourceName));
    }

    /**
     * 跳转更新页面
     *
     * @param resourceId 资源id
     * @param model      模型
     * @return 更新页面
     */
    @GetMapping("/update/{resourceId}")
    public String updatePage(@PathVariable("resourceId") Long resourceId, Model model)
    {
        Resource resource = resourceService.getById(resourceId);
        String typeName;
        if ("M".equals(resource.getResourceType()))
        {
            typeName = "菜单目录";
        }
        else if ("C".equals(resource.getResourceType()))
        {
            typeName = "子菜单";
        }
        else
        {
            typeName = "操作按钮";
        }
        model.addAttribute("typename", typeName);
        model.addAttribute("resource", resource);
        return "menu/update";
    }

    /**
     * 修改菜单
     *
     * @param resource 资源id
     * @return 统一结果
     */
    @PutMapping("/update/{resourceId}")
    @RequiresPermissions("system:resource:update")
    @ResponseBody
    public ResultVO update(
        @NotEmpty(message = "资源id不能为空") @PathVariable("resourceId") Long resourceId,
        Resource resource)
    {
        resource.setId(resourceId);
        return ResultVO.success(resourceService.updateById(resource));
    }
}